import * as echarts from 'echarts/core'
import { PieChart } from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  // 数据集组件
  DatasetComponent,
  // 内置数据转换器组件 (filter, sort)
  TransformComponent,
  LegendComponent
} from 'echarts/components'
import { LabelLayout, UniversalTransition } from 'echarts/features'
import { CanvasRenderer } from 'echarts/renderers'
import type {
  // 系列类型的定义后缀都为 SeriesOption
  PieSeriesOption
} from 'echarts/charts'
import type {
  // 组件类型的定义后缀都为 ComponentOption
  TitleComponentOption,
  TooltipComponentOption,
  GridComponentOption,
  LegendComponentOption,
  DatasetComponentOption
} from 'echarts/components'
import type { ComposeOption, EChartsType } from 'echarts/core'
import { CSSProperties, ReactElement, useCallback, useEffect, useRef } from 'react'
import { chartFontSize } from '@/utils/rem.ts'
import type { OptionDataItemObject, OptionDataValueNumeric } from 'echarts/types/src/util/types'

// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
type MyPieOption = ComposeOption<
  PieSeriesOption | TitleComponentOption | TooltipComponentOption | GridComponentOption | DatasetComponentOption | LegendComponentOption
>

// 注册必须的组件
echarts.use([
  TitleComponent,
  LegendComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  PieChart,
  LabelLayout,
  UniversalTransition,
  CanvasRenderer
])

const MyPieChart = ({
  option,
  pieData = {
    name: '数据啊',
    data: [],
    unit: '个',
    title: {
      text: '',
      subtext: ''
    }
  },
  domStyle,
  children,
  colors = ['#1FCAC9', '#F2A139', '#87A7BF']
}: {
  option?: MyPieOption
  pieData: {
    name: string
    data: Array<OptionDataItemObject<OptionDataValueNumeric>>
    unit: string
    title: {
      text: string
      subtext: string
    }
  }
  domStyle?: CSSProperties
  children?: ReactElement
  colors?: Array<string>
}) => {
  const domRef = useRef<HTMLDivElement>(null)
  const chartRef = useRef<EChartsType>()
  const chartStyle: CSSProperties = {
    width: '100%',
    minHeight: '50px',
    height: '100%',
    position: 'relative',
    ...domStyle
  }

  const chartOption: MyPieOption = {
    color: colors,
    title: {
      ...pieData.title,
      left: chartFontSize(60),
      top: chartFontSize(94),
      textAlign: 'center',
      itemGap: 6,
      textStyle: {
        fontSize: chartFontSize(28),
        color: '#2C2C2C',
        fontFamily: 'MicrosoftYaHei'
      },
      subtextStyle: {
        fontSize: chartFontSize(16),
        color: '#2C2C2C',
        fontFamily: 'MicrosoftYaHei'
      }
    },
    legend: {
      show: true,
      top: chartFontSize(78),
      right: chartFontSize(12),
      orient: 'vertical',
      icon: 'circle',
      textStyle: {
        rich: {
          name: {
            fontSize: chartFontSize(14),
            width: chartFontSize(50),
            color: '#57748B'
          },
          value: {
            width: chartFontSize(56),
            fontSize: chartFontSize(14),
            align: 'right',
            color: '#32393F'
          }
        }
      },
      formatter(name: string) {
        return `{name|${name}}  {value|${pieData.data.find((item) => item?.name === name)?.value ?? '-'}${pieData.unit}}`
      }
    },
    tooltip: {
      trigger: 'item'
    },
    series: [
      {
        name: pieData.name,
        type: 'pie',
        radius: ['35%', '45%'],
        center: [chartFontSize(60), chartFontSize(120)],
        itemStyle: {
          borderRadius: 6,
          borderColor: '#fff',
          borderWidth: 2
        },
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: false
          }
        },
        data: pieData.data
      }
    ],
    ...option
  }

  const resizeMyChart = useCallback(() => {
    chartRef.current?.resize()
  }, [])

  useEffect(() => {
    if (domRef.current) {
      chartRef.current = echarts.getInstanceByDom(domRef.current)
      if (!chartRef.current) {
        chartRef.current = echarts.init(domRef.current)
      }
      if (chartOption) chartRef.current?.setOption(chartOption)
    }
    window.addEventListener('resize', resizeMyChart)
    return () => {
      window.removeEventListener('resize', resizeMyChart)
    }
  }, [chartOption, resizeMyChart])

  return (
    <div
      style={{
        height: '100%',
        width: '100%',
        position: 'relative'
      }}>
      <div ref={domRef} style={chartStyle} />
      {children}
    </div>
  )
}

export default MyPieChart
